import { ref, unref } from 'vue'
import type { TablePaginationConfig } from 'ant-design-vue'
import { toInt } from './common'

export interface PaginationRequestFunc<T = any, U = any> {
  (params?: PaginateQuery<U>): Promise<PaginateResponse<T>>
}

export interface RequestFunc<T = any, U = any> {
  (params?: U): Promise<IResponse<T>>
}

export interface ErrorHandler {
  (err: any): void
}


/**
 * 通用分页接口请求
 */
export function usePagination<T, U>(req: PaginationRequestFunc<T, U>, err?: ErrorHandler) {
  const dataSource = ref<T[]>()
  const loading = ref<boolean>(false)
  const params = ref<PaginateQuery<U>>({})
  const pagination = ref<TablePaginationConfig>({
    current: 1,
    total: 0,
    showSizeChanger: true
  })
  const fetch = async () => {
    loading.value = true
    const res = await req(params.value!).catch(err || (() => {}))
    if (res) {
      dataSource.value = res.data.data
      pagination.value = {
        ...unref(pagination),
        current: toInt(res.data.current_page),
        total: toInt(res.data.total),
        pageSize: toInt(res.data.per_page),
      }
    }
    loading.value = false
  }
  return { dataSource, pagination, params, loading, fetch }
}

export function useRequest<T, U>(req: RequestFunc<T, U>, err?: ErrorHandler) {
  const dataSource = ref<T>()
  const loading = ref<boolean>(false)
  const params = ref<U>()
  const fetch = async () => {
    loading.value = true
    const res = await req(unref(params)).catch(err || (() => {}))
    if (res) dataSource.value = res.data
    loading.value = false
  }
  return { dataSource, loading, params, fetch }
}

/**
 * table select hook
 */
export function useTableSelection() {
  const selectedKeys = ref<any[]>([])
  const onSelectedChange = (keys: any[]) => {
    selectedKeys.value = keys
  }
  return {
    selectedKeys,
    onSelectedChange
  }
}

/**
 * 返回一个可切换的状态
 */
export function useSwitchable(def = false) {
  const state = ref<boolean>(def)
  const toggle = () => state.value = !state.value
  const on = () => state.value = true
  const off = () => state.value = false
  const update = (v: boolean) => state.value = v

  return { state, toggle, on, off, update }
}
